package com.lc.common.config;


import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * swagger 配置类
 *
 * @author YanHuan
 */
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {

    @Value("${swagger.apiPackage}")
    private final List<String> apiPackage = new ArrayList<>();
    @Value("${swagger.title}")
    private String title;
    @Value("${swagger.apiDes}")
    private String apiDes;

    private static final String MENU_ID = "menuId";
    private static final String CLOUD_TOKEN = "cloudToken";

    @Bean(value = "${swagger.bean}")
    @Order(value = 1)
    public Docket groupRestApi() {
        List<Predicate<RequestHandler>> predicateList = apiPackage.stream().map(RequestHandlerSelectors::basePackage).collect(Collectors.toList());
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(groupApiInfo())
                .select()
                .apis(Predicates.or(predicateList))
                .paths(PathSelectors.any())
                .build()
                .securityContexts(Lists.newArrayList(securityContextToken(), securityContextMenu()))
                .securitySchemes(Lists.<SecurityScheme>newArrayList(apiToken(), apiMenu()));
    }

    private ApiInfo groupApiInfo() {
        return new ApiInfoBuilder()
                .title(title)
                .description("<div style='font-size:14px;color:red;'>" + apiDes + "</div>")
                .termsOfServiceUrl("https://gitee.com/leichencode/lc-cloud")
                .version("1.0")
                .build();
    }


    private ApiKey apiToken() {
        return new ApiKey(CLOUD_TOKEN, CLOUD_TOKEN, "header");
    }

    private ApiKey apiMenu() {
        return new ApiKey(MENU_ID, MENU_ID, "header");
    }


    private SecurityContext securityContextToken() {
        return SecurityContext.builder()
                .securityReferences(defaultAuthToken())
                .forPaths(PathSelectors.regex("/.*"))
                .build();
    }

    private SecurityContext securityContextMenu() {
        return SecurityContext.builder()
                .securityReferences(defaultAuthMenu())
                .forPaths(PathSelectors.regex("/.*"))
                .build();
    }

    List<SecurityReference> defaultAuthToken() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Lists.newArrayList(new SecurityReference(CLOUD_TOKEN, authorizationScopes));
    }

    List<SecurityReference> defaultAuthMenu() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Lists.newArrayList(new SecurityReference(MENU_ID, authorizationScopes));
    }

}